module ecs{
    /**
     * 将渲染器添加到场景中，并处理对RenderableComponent.render和Entity.debugRender的所有实际调用
     * 一个简单的Renderer可以只启动Graphics.instanceGraphics.batcher，也可以创建自己的本地Graphics实例（如果需要它来进行某种自定义渲染）
     * 请注意，最佳做法是确保所有渲染到RenderTarget的Renderer都具有较低的renderOrders以避免出现问题
     * 给他们一个负的renderOrder是解决这个问题的好策略。
     */
    export abstract class Renderer implements IComparable<Renderer> {
        /**
         * 指定场景将调用渲染器的顺序
         */
        public readonly RenderOrder: number = 0;

        /**
         * 如果renderTarget不为null，则此渲染器将渲染到RenderTarget中，而不是渲染到屏幕中
         */
        public RenderTexture: RenderTexture;

        /**
         * 此渲染器用于渲染的相机（实际上是其transformMatrix和边界用于剔除）。 这是一个方便的字段，不是必需的。 
         * 渲染器子类可以选择调用beginRender时使用的相机。
         */
        public Camera: Camera;

        /**
         * 如果为true，则在所有PostProcessor完成后，Scene将调用render方法。 
         * 在调用Scene.addRenderer之前必须将其设置为true，并且Renderer不应具有renderTexture。 
         * 使用这种类型的Renderer的主要原因是，您可以在不对场景其余部分进行后期处理的情况下呈现UI。 
         * ScreenSpaceRenderer是一个将其设置为true的示例渲染器。
         */
        public WantsToRenderAfterPostProcessors;

        constructor(renderOrder: number, camera: Camera){
            this.Camera = camera;
            this.RenderOrder = renderOrder;
        }

        /** 将渲染器添加到场景时调用 */
        public OnAddedToScene(scene: Scene){}

        /**
         * 调整默认场景RenderTarget的大小时以及在场景已开始时添加渲染器时调用。 
         * 默认实现调用RenderTexture.onSceneBackBufferSizeChanged，以便在必要时可以适当调整自身大小。
         * @param newWidth 
         * @param newHeight 
         */
        public OnSceneBackBufferSizeChanged(newWidth: number, newHeight: number){
            if (this.RenderTexture){
                return this.RenderTexture.OnSceneBackBufferSizeChanged(newWidth, newHeight);
            }
            return null;
        };

        CompareTo(other: Renderer): number {
            return this.RenderOrder.CompareTo(other.RenderOrder);
        }
    }
}